package com.hsu.hsurpc.serializer;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * Kryo 序列化器，用于高效的对象序列化与反序列化
 * @Author Hsu琛君珩
 * @Date 2024-09-19 17:11
 * @Description
 * @Version: v1.0.0
 */
public class KryoSerializer implements Serializer {

    // 使用 ThreadLocal 确保每个线程有独立的 Kryo 实例，防止多线程竞争
    private static final ThreadLocal<Kryo> KRYO_THREAD_LOCAL = ThreadLocal.withInitial(() -> {
        Kryo kryo = new Kryo();
        kryo.setRegistrationRequired(false); // 不要求类提前注册
        return kryo;
    });

    /**
     * 将对象序列化为字节数组
     *
     * @param obj 需要序列化的对象
     * @return 序列化后的字节数组
     */
    @Override
    public <T> byte[] serialize(T obj) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        Output output = new Output(byteArrayOutputStream);

        // 获取当前线程的 Kryo 实例，序列化对象
        KRYO_THREAD_LOCAL.get().writeObject(output, obj);
        output.close();

        return new byte[0];
    }

    /**
     * 将字节数组反序列化为对象
     *
     * @param bytes 字节数组
     * @param classType 需要反序列化成的对象类型
     * @return 反序列化后的对象
     */
    @Override
    public <T> T deserialize(byte[] bytes, Class<T> classType) {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        Input input = new Input();

        // 使用 Kryo 进行反序列化
        T result = KRYO_THREAD_LOCAL.get().readObject(input, classType);
        input.close();

        return result;
    }
}
